import { WuziqiBoard } from "./WuziqiBoard";

// 五子棋AI类
export class WuziqiAi {
    player: number;
    maxDepth: number;

    constructor(player: number, maxDepth: number = 3) {
        this.player = player; // AI玩家编号（2）
        this.maxDepth = maxDepth;
    }

    // 获取AI的移动
    getMove(board: WuziqiBoard): [number, number] {
        const startTime = Date.now();
        const [bestMove, _] = this.minimax(board, this.maxDepth, -Infinity, Infinity, true);
        const endTime = Date.now();
        console.log(`AI思考时间: ${endTime - startTime}ms`);
        return bestMove || [Math.floor(board.size / 2), Math.floor(board.size / 2)];
    }

    // Minimax算法（带Alpha-Beta剪枝）
    minimax(
        board: WuziqiBoard,
        depth: number,
        alpha: number,
        beta: number,
        maximizingPlayer: boolean
    ): [[number, number] | null, number] {
        // 终止条件：达到最大深度或游戏结束
        if (depth === 0 || board.gameOver || board.isDraw()) {
            return [null, this.evaluateBoard(board)];
        }

        let bestMove: [number, number] | null = null;
        let bestValue = maximizingPlayer ? -Infinity : Infinity;

        // 获取可能的移动
        const possibleMoves = this.getPossibleMoves(board);

        for (const [row, col] of possibleMoves) {
            // 创建新棋盘模拟移动
            const newBoard = board.clone();
            newBoard.makeMove(row, col, maximizingPlayer ? this.player : 3 - this.player);

            // 递归调用minimax
            const [_, value] = this.minimax(newBoard, depth - 1, alpha, beta, !maximizingPlayer);

            if (maximizingPlayer) {
                if (value > bestValue) {
                    bestValue = value;
                    bestMove = [row, col];
                }
                alpha = Math.max(alpha, bestValue);
            } else {
                if (value < bestValue) {
                    bestValue = value;
                    bestMove = [row, col];
                }
                beta = Math.min(beta, bestValue);
            }

            // Alpha-Beta剪枝
            if (alpha >= beta) {
                break;
            }
        }

        return [bestMove, bestValue];
    }

    // 评估棋盘状态（启发式评估函数）
    evaluateBoard(board: WuziqiBoard): number {
        let score = 0;

        // 检查每个位置
        for (let row = 1; row <= board.size; row++) {
            for (let col = 1; col <= board.size; col++) {
                if (board.board[row][col].status !== 0) {
                    // 评估玩家棋子
                    if (board.board[row][col].status === this.player) {
                        score += this.evaluatePosition(board, row, col, this.player);
                    }
                    // 评估对手棋子
                    else {
                        score -= this.evaluatePosition(board, row, col, 3 - this.player) * 0.8;
                    }
                }
            }
        }

        return score;
    }

    // 评估特定位置
    evaluatePosition(board: WuziqiBoard, row: number, col: number, player: number): number {
        let score = 0;
        const directions = [
            [0, 1], [1, 0], [1, 1], [1, -1] // 水平、垂直、对角线、反对角线
        ];

        for (const [dx, dy] of directions) {
            score += this.evaluateDirection(board, row, col, dx, dy, player);
        }

        return score;
    }

    // 评估特定方向
    evaluateDirection(
        board: WuziqiBoard,
        row: number,
        col: number,
        dx: number,
        dy: number,
        player: number
    ): number {
        let score = 0;
        let count = 1; // 当前位置的棋子
        let openEnds = 0;

        // 向前检查
        let blocked = false;
        for (let i = 1; i <= 4; i++) {
            const newRow = row + dx * i;
            const newCol = col + dy * i;

            if (newRow < 1 || newRow > board.size || newCol < 1 || newCol > board.size) {
                blocked = true;
                break;
            }

            if (board.board[newRow][newCol].status === player) {
                count++;
            } else if (board.board[newRow][newCol].status === 0) {
                openEnds++;
                break;
            } else {
                blocked = true;
                break;
            }
        }

        // 向后检查
        for (let i = 1; i <= 4; i++) {
            const newRow = row - dx * i;
            const newCol = col - dy * i;

            if (newRow < 1 || newRow > board.size || newCol < 1 || newCol > board.size) {
                blocked = true;
                break;
            }

            if (board.board[newRow][newCol].status === player) {
                count++;
            } else if (board.board[newRow][newCol].status === 0) {
                openEnds++;
                break;
            } else {
                blocked = true;
                break;
            }
        }

        // 根据连子数和开放程度评分
        if (count >= 5) {
            score += 100000; // 五连
        } else if (count === 4) {
            if (openEnds === 2) score += 10000; // 活四
            else if (openEnds === 1) score += 1000; // 冲四
        } else if (count === 3) {
            if (openEnds === 2) score += 1000; // 活三
            else if (openEnds === 1) score += 200; // 眠三
        } else if (count === 2) {
            if (openEnds === 2) score += 100; // 活二
            else if (openEnds === 1) score += 50; // 眠二
        }

        return score;
    }

    // 获取可能的移动（只考虑有棋子周围的空位）
    getPossibleMoves(board: WuziqiBoard): [number, number][] {
        const moves: [number, number][] = [];
        const size = board.size;

        // 如果棋盘为空，返回中心点
        let isEmpty = true;
        for (let row = 1; row <= size; row++) {
            for (let col = 1; col <= size; col++) {
                if (board.board[row][col].status !== 0) {
                    isEmpty = false;
                    break;
                }
            }
            if (!isEmpty) break;
        }

        if (isEmpty) {
            return [[Math.floor(size / 2), Math.floor(size / 2)]];
        }

        // 获取所有有棋子周围的空位
        for (let row = 1; row <= size; row++) {
            for (let col = 1; col <= size; col++) {

                if (board.board[row][col].status !== 0) continue;

                // 检查周围2格内是否有棋子
                let hasNeighbor = false;
                for (let i = -2; i <= 2 && !hasNeighbor; i++) {
                    for (let j = -2; j <= 2; j++) {
                        if (i === 0 && j === 0) continue;

                        let newRow = row + i;
                        let newCol = col + j;

                        if (newRow >= 1 && newRow <= size &&
                            newCol >= 1 && newCol <= size &&
                            board.board[newRow][newCol].status !== 0) {
                            hasNeighbor = true;
                            break;
                        }
                    }
                }

                if (hasNeighbor) {
                    moves.push([row, col]);
                }
            }
        }

        return moves;
    }
}
